#include "common.h"

#include "object.h"
#include "actor.h"
#include "pawn.h"

#include "scene.h"

Scene::Scene()
:	_isDeferredRendering( false )
,	_isSceneReadyToRender( false )
,	_pCamera( NULL )
{
}

Scene::~Scene()
{
	if( _pCamera )
	{
		delete _pCamera;
	}

	ActorList::iterator it = _actorList.begin();
	for( ; it != _actorList.end(); ++it )
	{
		delete ( *it );
	}
}

void Scene::AddActor( Actor* pActor )
{
	_actorList.push_back( pActor );
}

void Scene::AddUI( const std::string& name, UI* pUI )
{
	_uiList[ name ] = pUI;
}

void Scene::DeferredRendering()
{
	if( _actorList.empty() )
	{
		return;
	}

	ActorListIter it = _actorList.begin();
	for( ; it != _actorList.end(); ++it )
	{
		if( ( *it )->IsA( Pawn::GetTypeInfo() ) )
		{
			Pawn& pawn = *( ( Pawn* )( *it ) );
		}
	}
}

void Scene::DrawScene( float time )
{
	LPDIRECT3DDEVICE9 device = Core::GetInstance().GetD3dDevice();
	device->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xFFFFFFFF, 1.0f, 0 );
	device->BeginScene();

	if( !_uiList.empty() )
	{
		UIListIter it = _uiList.begin();
		for( ; it != _uiList.end(); ++it )
		{
			it->second->Draw();
		}
	}

	// Render
	if( _isDeferredRendering )
	{
		// Deferred rendering
		DeferredRendering();
	}
	else
	{
		// Foward rendering
		FowardRendering();
	}

	if( false )
	{
		// Shadow map
	}

	device->EndScene();
	device->Present( NULL, NULL, NULL, NULL );
}

Actor* Scene::FindActor( const std::string& actorName )
{
	if( _actorList.empty() )
	{
		return NULL;
	}

	ActorListIter it = _actorList.begin();
	for( ; it != _actorList.end(); ++it )
	{
		if( ( *it )->GetName() == actorName )
		{
			return ( *it );
		}
	}
	return NULL;
}

UI* Scene::FindUI( const std::string& uiName )
{
	if( _uiList.empty() )
	{
		return NULL;
	}

	UIListIter it = _uiList.find( uiName );
	if( it != _uiList.end() )
	{
		return it->second;
	}

	return NULL;
}

void Scene::FowardRendering()
{
	if( _actorList.empty() )
	{
		return;
	}

	ActorListIter it = _actorList.begin();
	for( ; it != _actorList.end(); ++it )
	{
		if( ( *it )->IsA( Pawn::GetTypeInfo() ) )
		{
			Pawn& pawn = *( ( Pawn * )( *it ) );
			pawn.Render( "FowardRendering" );
		}
	}
}
